/**
 * Copyright 2018 asiainfo Inc.
 **/
package com.myz.app.utils;

import com.google.common.collect.Lists;
import org.apache.shiro.codec.Base64;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.io.*;
import java.util.Collection;
import java.util.List;

/**
 * 因为Jedis API KEY和Value相同，同为String或同为byte[]为了方便扩展下面的方法
 * Spring提供的 SerializationUtils系列化工具，提供了serialize()和deserialize()两种方法
 *
 * @author maoyz on 2018/6/11
 * @version: v1.0
 */
public class SerializeUtils /*extends SerializationUtils*/ {

  private static Logger logger = LoggerFactory.getLogger(SerializeUtils.class);

  /**
   * 序列化成String
   *
   * @param obj
   * @return
   */
  public static String serializeToString(Object obj) {
    if (obj == null) {
      return null;
    }
    try {
      byte[] result = serialize(obj);
      // 2 base64编码
      return Base64.encodeToString(result);
    } catch (Exception e) {
      throw new RuntimeException("serializeToString fail");
    }
  }

  /**
   * 序列化 byte[]
   *
   * @param obj
   * @return
   */
  public static byte[] serialize(Object obj) {
    byte[] result = null;
    // 1 实现序列化
    ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream(128);
    try {
      ObjectOutputStream objectOutputStream = new ObjectOutputStream(byteArrayOutputStream);
      // 判断类型
      if (!(obj instanceof Serializable)) {
        throw new RuntimeException(obj.getClass().getSimpleName() + "obj not Serializable");
      }
      objectOutputStream.writeObject(obj);
      objectOutputStream.flush();
      result = byteArrayOutputStream.toByteArray();
    } catch (Exception e) {
      throw new RuntimeException("serialize session fail:" + e);
    }
    return result;
  }

  /**
   * 反序列化
   *
   * @param base64
   * @return
   */
  public static Object deserializeFromString(String base64) {
    if (base64 == null || "".equals(base64)){
      return null;
    }
    try {
      // 1 base64解码
      byte[] decode = Base64.decode(base64);
      // 2 反序列化
      return deserialize(decode);
    } catch (Exception e) {
      throw new RuntimeException("deserialize session fail:" + e);
    }
  }

  /**
   * 反序列化 byte[]
   * @param bytes
   * @return
   */
  public static Object deserialize(byte[] bytes) {
    Object result = null;
    ByteArrayInputStream byteArrayInputStream = new ByteArrayInputStream(bytes);
    try {
      ObjectInputStream objectInputStream = new ObjectInputStream(byteArrayInputStream);
      result = objectInputStream.readObject();
    } catch (Exception e) {
      throw new RuntimeException("deserialize fail");
    }
    return result;
  }

  /**
   * 反序列化字符窜集合
   *
   * @param base64s
   * @param <T>
   * @return
   */
  public static <T> Collection<T> deserializeFromStringController(Collection<String> base64s) {
    try {
      // 使用泛型
      List<T> lists = Lists.newLinkedList();
      for (String base64 : base64s) {
        byte[] decode = Base64.decode(base64);
        T t = (T) deserialize(decode);
        lists.add(t);
      }
      return lists;
    } catch (Exception e) {
      throw new RuntimeException("deserialize session fail:" + e);
    }
  }
}
